package com.shaw.study.springx.beans;

import com.shaw.study.springx.annotation.Transaction;
import com.shaw.study.springx.aop.AopProxy;
import com.shaw.study.springx.aop.TransactionAopProxy;

import java.lang.reflect.Method;

/**
 * Created by asus on 2018/4/30.
 */
public class BeanWapper {
    //包装后的bean实例
    private Object wapperBeanInstance;
    //原生的bean实例
    private Object originalBeanInstance;
    //事件响应，监听器
    private BeanPostProcessor beanPostProcessor;

    public BeanWapper(Object beanInstance){
        init(beanInstance,null,null);
    }

    public BeanWapper(Object beanInstance,AopProxy aopProxy,BeanPostProcessor beanPostProcessor){
        init(beanInstance,aopProxy,beanPostProcessor);
    }

    private void init(Object beanInstance,AopProxy aopProxy,BeanPostProcessor beanPostProcessor){
        this.originalBeanInstance = beanInstance;
        this.beanPostProcessor = beanPostProcessor;
        this.wapperBeanInstance = doWrap(aopProxy,beanInstance);
    }

    public Object doWrap(AopProxy aopProxy,Object beanInstance){
        if(beTransactionPorxy(beanInstance.getClass())){
            beanInstance = getTransactionProxy(beanInstance);
        }
        return aopProxy.getProxy(beanInstance);
    }

    public Object getTransactionProxy(Object beanInstance){
        return new TransactionAopProxy(beanInstance).getProxy();
    }
    public Boolean beTransactionPorxy(Class clazz){
        Method[] methods = clazz.getMethods();
        for(Method method:methods){
            if(method.isAnnotationPresent(Transaction.class)){
                return true;
            }
        }
        return false;
    }

    public BeanPostProcessor getBeanPostProcessor() {
        return beanPostProcessor;
    }

    public void setBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        this.beanPostProcessor = beanPostProcessor;
    }

    public Object getWapperBeanInstance() {
        return wapperBeanInstance;
    }

    public Object getOriginalBeanInstance() {
        return originalBeanInstance;
    }

    public Class<?> getWapperClass(){
        return wapperBeanInstance.getClass();
    }
}
